package mynl

/////////////////////////////////////////////////////////////////////////
// 词法分析
// 本节没有提供词法分析器，直接提供了一个Token串。
// 语法分析程序可以从Token串中依次读出一个个Token，也可以重新定位Token串的当前读取位置。

//Token的类型
type TokenKind int

const (
	TokenKind_Keyword TokenKind = iota
	TokenKind_Identifier
	TokenKind_StringLiteral
	TokenKind_Seperator
	TokenKind_Operator
	TokenKind_EOF
)

func (selfx *TokenKind) String() string {
	var x = []string{"Keyword", "Identifier", "StringLiteral", "Seperator", "Operator", "EOF"}
	return x[*selfx]
}

// 代表一个Token的数据结构
type Token struct {
	Kind TokenKind
	Text string
}

/**
 * 简化的词法分析器
 * 语法分析器从这里获取Token。
 * 支持下面两个操作：
 * next(): 返回当前的Token，并移向下一个Token。
 * peek(): 返回当前的Token，但不移动当前位置。
 */
type Tokenizer struct {
	tokens []Token
	pos    int
}

func NewTokenizer(tokens []Token) *Tokenizer {
	return &Tokenizer{
		pos:    0,
		tokens: tokens,
	}
}

//获取下一个token，pos+1
func (selfx *Tokenizer) next() Token {
	if selfx.pos < len(selfx.tokens) {
		selfx.pos += 1
		return selfx.tokens[selfx.pos-1]
	} else {
		//如果已经到了末尾，总是返回EOF
		return selfx.tokens[selfx.pos]
	}
}

//获取下一个token，但不修改pos
func (selfx *Tokenizer) peek() Token {
	if selfx.pos < len(selfx.tokens) {
		return selfx.tokens[selfx.pos]
	} else {
		//如果已经到了末尾，总是返回EOF
		return selfx.tokens[selfx.pos]
	}
}

func (selfx *Tokenizer) position() int {
	return selfx.pos
}

func (selfx *Tokenizer) traceBack(newPos int) {
	selfx.pos = newPos
}
